<!--
  变换控制器组件
  提供图层的拖拽、缩放、旋转控制
-->
<template>
  <div class="transform-controls" v-if="boundingBox">
    <!-- 边界框 -->
    <div 
      class="bounding-box"
      :style="boundingBoxStyle"
    >
      <!-- 角落控制点 -->
      <div 
        v-for="corner in corners"
        :key="corner.type"
        :class="['control-point', 'corner', corner.type]"
        :style="corner.style"
        @mousedown="startTransform('scale', corner.type, $event)"
      />
      
      <!-- 边缘控制点 -->
      <div 
        v-for="edge in edges"
        :key="edge.type"
        :class="['control-point', 'edge', edge.type]"
        :style="edge.style"
        @mousedown="startTransform('scale', edge.type, $event)"
      />
      
      <!-- 旋转控制点 -->
      <div 
        class="control-point rotation"
        :style="rotationPointStyle"
        @mousedown="startTransform('rotate', 'rotation', $event)"
      >
        <n-icon size="12">
          <RefreshOutline />
        </n-icon>
      </div>
      
      <!-- 中心移动区域 -->
      <div 
        class="move-area"
        @mousedown="startTransform('move', 'center', $event)"
      />
    </div>
    
    <!-- 变换信息显示 -->
    <div 
      v-if="showTransformInfo && transformInfo"
      class="transform-info"
      :style="transformInfoStyle"
    >
      <n-text depth="2" style="font-size: 12px; font-family: monospace;">
        {{ transformInfo }}
      </n-text>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import { NIcon, NText } from 'naive-ui'
import { RefreshOutline } from '@vicons/ionicons5'
import type { EditorLayer, ViewportState } from '../../stores/editor'

// Props
interface Props {
  layers: EditorLayer[]
  viewport: ViewportState
}

const props = defineProps<Props>()

// Events
const emit = defineEmits(['transform'])

// 状态
const isTransforming = ref(false)
const transformType = ref<'move' | 'scale' | 'rotate'>('move')
const transformHandle = ref<string>('')
const startMousePos = ref({ x: 0, y: 0 })
const startTransformData = ref<any>(null)
const showTransformInfo = ref(false)
const transformInfo = ref('')

// 计算边界框
const boundingBox = computed(() => {
  if (props.layers.length === 0) return null
  
  let minX = Infinity
  let minY = Infinity
  let maxX = -Infinity
  let maxY = -Infinity
  
  for (const layer of props.layers) {
    const { position, scale } = layer
    const width = 100 * scale.x // 假设默认尺寸为100
    const height = 100 * scale.y
    
    const left = position.x - width / 2
    const right = position.x + width / 2
    const top = position.y - height / 2
    const bottom = position.y + height / 2
    
    minX = Math.min(minX, left)
    minY = Math.min(minY, top)
    maxX = Math.max(maxX, right)
    maxY = Math.max(maxY, bottom)
  }
  
  return {
    x: minX,
    y: minY,
    width: maxX - minX,
    height: maxY - minY,
    centerX: (minX + maxX) / 2,
    centerY: (minY + maxY) / 2
  }
})

// 边界框样式
const boundingBoxStyle = computed(() => {
  if (!boundingBox.value) return {}

  const { x, y, width, height } = boundingBox.value
  const { zoom } = props.viewport

  return {
    left: `${x * zoom}px`,
    top: `${y * zoom}px`,
    width: `${width * zoom}px`,
    height: `${height * zoom}px`
  }
})

// 控制点配置
const corners = computed(() => {
  if (!boundingBox.value) return []
  
  const size = 8
  const offset = size / 2
  
  return [
    {
      type: 'top-left',
      style: { left: `-${offset}px`, top: `-${offset}px` }
    },
    {
      type: 'top-right',
      style: { right: `-${offset}px`, top: `-${offset}px` }
    },
    {
      type: 'bottom-left',
      style: { left: `-${offset}px`, bottom: `-${offset}px` }
    },
    {
      type: 'bottom-right',
      style: { right: `-${offset}px`, bottom: `-${offset}px` }
    }
  ]
})

const edges = computed(() => {
  if (!boundingBox.value) return []
  
  const size = 8
  const offset = size / 2
  
  return [
    {
      type: 'top',
      style: { left: '50%', top: `-${offset}px`, transform: 'translateX(-50%)' }
    },
    {
      type: 'right',
      style: { right: `-${offset}px`, top: '50%', transform: 'translateY(-50%)' }
    },
    {
      type: 'bottom',
      style: { left: '50%', bottom: `-${offset}px`, transform: 'translateX(-50%)' }
    },
    {
      type: 'left',
      style: { left: `-${offset}px`, top: '50%', transform: 'translateY(-50%)' }
    }
  ]
})

// 旋转控制点样式
const rotationPointStyle = computed(() => {
  const offset = 20
  return {
    left: '50%',
    top: `-${offset}px`,
    transform: 'translateX(-50%)'
  }
})

// 变换信息样式
const transformInfoStyle = computed(() => {
  if (!boundingBox.value) return {}

  const { centerX, centerY } = boundingBox.value
  const { zoom } = props.viewport

  return {
    left: `${centerX * zoom}px`,
    top: `${(centerY - 50) * zoom}px`,
    transform: 'translateX(-50%)'
  }
})

// 开始变换
const startTransform = (type: 'move' | 'scale' | 'rotate', handle: string, event: MouseEvent) => {
  event.preventDefault()
  event.stopPropagation()
  
  isTransforming.value = true
  transformType.value = type
  transformHandle.value = handle
  startMousePos.value = { x: event.clientX, y: event.clientY }
  showTransformInfo.value = true
  
  // 保存初始状态
  startTransformData.value = {
    layers: props.layers.map(layer => ({
      id: layer.id,
      position: { ...layer.position },
      scale: { ...layer.scale },
      rotation: layer.rotation
    })),
    boundingBox: { ...boundingBox.value! }
  }
  
  document.addEventListener('mousemove', handleTransform)
  document.addEventListener('mouseup', endTransform)
  document.body.style.cursor = getCursor(type, handle)
}

// 处理变换
const handleTransform = (event: MouseEvent) => {
  if (!isTransforming.value || !startTransformData.value) return
  
  const deltaX = event.clientX - startMousePos.value.x
  const deltaY = event.clientY - startMousePos.value.y
  
  switch (transformType.value) {
    case 'move':
      handleMove(deltaX, deltaY)
      break
    case 'scale':
      handleScale(deltaX, deltaY)
      break
    case 'rotate':
      handleRotate(deltaX, deltaY)
      break
  }
}

// 处理移动
const handleMove = (deltaX: number, deltaY: number) => {
  const { zoom } = props.viewport
  const scaledDeltaX = deltaX / zoom
  const scaledDeltaY = deltaY / zoom
  
  for (const layerData of startTransformData.value.layers) {
    const newPosition = {
      x: layerData.position.x + scaledDeltaX,
      y: layerData.position.y + scaledDeltaY
    }
    
    emit('transform', layerData.id, { position: newPosition })
  }
  
  transformInfo.value = `X: ${Math.round(scaledDeltaX)}, Y: ${Math.round(scaledDeltaY)}`
}

// 处理缩放
const handleScale = (deltaX: number, deltaY: number) => {
  const { zoom } = props.viewport
  const { boundingBox: startBox } = startTransformData.value
  
  let scaleX = 1
  let scaleY = 1
  
  // 根据控制点计算缩放比例
  switch (transformHandle.value) {
    case 'top-left':
      scaleX = (startBox.width - deltaX / zoom) / startBox.width
      scaleY = (startBox.height - deltaY / zoom) / startBox.height
      break
    case 'top-right':
      scaleX = (startBox.width + deltaX / zoom) / startBox.width
      scaleY = (startBox.height - deltaY / zoom) / startBox.height
      break
    case 'bottom-left':
      scaleX = (startBox.width - deltaX / zoom) / startBox.width
      scaleY = (startBox.height + deltaY / zoom) / startBox.height
      break
    case 'bottom-right':
      scaleX = (startBox.width + deltaX / zoom) / startBox.width
      scaleY = (startBox.height + deltaY / zoom) / startBox.height
      break
    case 'top':
    case 'bottom':
      scaleY = transformHandle.value === 'top' 
        ? (startBox.height - deltaY / zoom) / startBox.height
        : (startBox.height + deltaY / zoom) / startBox.height
      break
    case 'left':
    case 'right':
      scaleX = transformHandle.value === 'left'
        ? (startBox.width - deltaX / zoom) / startBox.width
        : (startBox.width + deltaX / zoom) / startBox.width
      break
  }
  
  // 保持最小缩放比例
  scaleX = Math.max(0.1, scaleX)
  scaleY = Math.max(0.1, scaleY)
  
  // 等比缩放（按住Shift键）
  if (event.shiftKey) {
    const avgScale = (scaleX + scaleY) / 2
    scaleX = scaleY = avgScale
  }
  
  for (const layerData of startTransformData.value.layers) {
    const newScale = {
      x: layerData.scale.x * scaleX,
      y: layerData.scale.y * scaleY
    }
    
    emit('transform', layerData.id, { scale: newScale })
  }
  
  transformInfo.value = `Scale: ${Math.round(scaleX * 100)}%, ${Math.round(scaleY * 100)}%`
}

// 处理旋转
const handleRotate = (deltaX: number, deltaY: number) => {
  if (!boundingBox.value) return
  
  const { centerX, centerY } = boundingBox.value
  const { zoom, panX, panY } = props.viewport
  
  const centerScreenX = centerX * zoom + panX
  const centerScreenY = centerY * zoom + panY
  
  const startAngle = Math.atan2(
    startMousePos.value.y - centerScreenY,
    startMousePos.value.x - centerScreenX
  )
  
  const currentAngle = Math.atan2(
    startMousePos.value.y + deltaY - centerScreenY,
    startMousePos.value.x + deltaX - centerScreenX
  )
  
  let deltaAngle = (currentAngle - startAngle) * 180 / Math.PI
  
  // 15度吸附（按住Shift键）
  if (event.shiftKey) {
    deltaAngle = Math.round(deltaAngle / 15) * 15
  }
  
  for (const layerData of startTransformData.value.layers) {
    const newRotation = layerData.rotation + deltaAngle
    emit('transform', layerData.id, { rotation: newRotation })
  }
  
  transformInfo.value = `Rotation: ${Math.round(deltaAngle)}°`
}

// 结束变换
const endTransform = () => {
  isTransforming.value = false
  showTransformInfo.value = false
  transformInfo.value = ''
  startTransformData.value = null
  
  document.removeEventListener('mousemove', handleTransform)
  document.removeEventListener('mouseup', endTransform)
  document.body.style.cursor = ''
}

// 获取光标样式
const getCursor = (type: string, handle: string): string => {
  if (type === 'move') return 'move'
  if (type === 'rotate') return 'grab'
  
  if (type === 'scale') {
    switch (handle) {
      case 'top-left':
      case 'bottom-right':
        return 'nw-resize'
      case 'top-right':
      case 'bottom-left':
        return 'ne-resize'
      case 'top':
      case 'bottom':
        return 'n-resize'
      case 'left':
      case 'right':
        return 'e-resize'
    }
  }
  
  return 'default'
}

// 生命周期
onBeforeUnmount(() => {
  if (isTransforming.value) {
    endTransform()
  }
})
</script>

<style lang="scss" scoped>
.transform-controls {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 100;
}

.bounding-box {
  position: absolute;
  border: 2px solid var(--primary-color);
  pointer-events: none;
  
  &::before {
    content: '';
    position: absolute;
    top: -1px;
    left: -1px;
    right: -1px;
    bottom: -1px;
    border: 1px solid rgba(255, 255, 255, 0.8);
    pointer-events: none;
  }
}

.control-point {
  position: absolute;
  width: 8px;
  height: 8px;
  background: var(--primary-color);
  border: 1px solid white;
  pointer-events: auto;
  cursor: pointer;
  
  &.corner {
    border-radius: 2px;
    
    &.top-left,
    &.bottom-right {
      cursor: nw-resize;
    }
    
    &.top-right,
    &.bottom-left {
      cursor: ne-resize;
    }
  }
  
  &.edge {
    &.top,
    &.bottom {
      cursor: n-resize;
    }
    
    &.left,
    &.right {
      cursor: e-resize;
    }
  }
  
  &.rotation {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;
    color: var(--primary-color);
    cursor: grab;
    
    &:active {
      cursor: grabbing;
    }
  }
  
  &:hover {
    transform: scale(1.2);
  }
}

.move-area {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  cursor: move;
  pointer-events: auto;
}

.transform-info {
  position: absolute;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 101;
}
</style>
